package com.chenzhiling.study.Io

import com.sshtools.sftp.{SftpClient, SftpFile}

import java.io.{File, FileInputStream, FileOutputStream, IOException, InputStream}
import java.nio.ByteBuffer
import java.nio.channels.FileChannel
import scala.collection.mutable.{ArrayBuffer, ListBuffer}

/**
 * @Author: CHEN ZHI LING
 * @Date: 2021/5/14
 * @Description: 利用scala实现文件相关功能
 */
object ScalaIo {


  /**
   * 复制指定路径下所有文件
   *
   * @param inputDire  输入路径
   * @param outputDire 输出路径
   * @return 结果
   */

  def copyDirectory(inputDire: String, outputDire: String): String = {
    val sourceFile = new File(inputDire)
    //检查输入路径是否存在
    if (!sourceFile.exists()) {
      return "路径不存在"
    }
    val destDir = new File(outputDire)
    //目的目录不存在,创建目录
    if (!destDir.exists()) {
      destDir.mkdir()
    }
    val fileList: Array[File] = sourceFile.listFiles()
    //便利所有文件
    for (file <- fileList) {
      //需要被复制的文件地址
      val fileFrom: String = inputDire + File.separator + file.getName
      //复制后的文件地址
      val fileTo: String = outputDire + File.separator + file.getName
      //文件复制
      if (file.isFile) {
        copyFileTo(fileFrom, fileTo)
      }
      //是文件夹递归调用
      if (file.isDirectory) {
        copyDirectory(fileFrom, fileTo)
      }
    }
    "复制成功"
  }


  /**
   * 文件复制
   * 使用字节流进行文件复制
   *
   * @param inputFile  需要复制的文件地址
   * @param outputFile 复制后文件输出的地址
   * @return ture--成功 false --失败
   */


  def copyFileTo(inputFile: String, outputFile: String): Boolean = {
    //打开输入流
    try {
      val fileInputStream = new FileInputStream(inputFile)
      //打开输出留
      val fileOutputStream = new FileOutputStream(outputFile)
      //字节数组
      val buffer = new Array[Byte](1024)
      //输入流写入输出流
      while (fileInputStream.read(buffer) != -1) {
        fileOutputStream.write(buffer)
      }
      //关闭输出流
      fileOutputStream.close()
      //关闭输入流
      fileInputStream.close()
      true
    } catch {
      case _: IOException =>
        println(inputFile + "复制失败")
        false
    }

  }


  /**
   * 创建指定大小的文件
   * @param path 路径
   * @param size 大小
   * @return
   */
  def creatFile(path: String,size: Long) : Boolean= {
    val file = new File(path)
    var fos: FileOutputStream = null
    var output : FileChannel = null
    try {
      fos = new FileOutputStream(file)
      output = fos.getChannel
      output.write(ByteBuffer.allocate(1), size - 1)
      true
    } catch {
      case ex: IOException =>
        ex.printStackTrace()
        false
    }finally {
      output.close()
      fos.close()
    }
  }


  /**
   * 列出指定路径下的所有文件
   * @param dir 本地路径
   * @return 文件数组
   */
  def listDirectory(dir: File): Array[File] = {
    dir.listFiles.filter((_: File).isFile) ++
      dir.listFiles.filter((_: File).isDirectory).flatMap(listDirectory)
  }

  /**
   * 遍历远程机器指定路径下的所有文件
   * @param remotePath 远程机器路径
   * @param client sftp客户端
   * @return
   */
  def listRemoteFiles(remotePath:String,client:SftpClient): Array[SftpFile] ={
    client.ls(remotePath).filter((_:SftpFile).isFile) ++
      //过滤上级目录,文件路径名以.结尾会有bug
      client.ls(remotePath).filter(!(_:SftpFile).toString.endsWith("."))
        .filter((_: SftpFile).isDirectory ).flatMap((subPath: SftpFile) => listRemoteFiles(subPath.toString,client))
  }

  /**
   * 获取文件后缀名，不带.
   * @param fileName 文件名
   * @return
   */
  def getFileSuffix(fileName: String): String = {
    if (fileName.nonEmpty) {
      val dot: Int = fileName.lastIndexOf(".")
      if ((dot > -1) && (dot < (fileName.length - 1))) {
        return fileName.substring(dot + 1)
      }
    }
    fileName
  }


  /**
   * 将一个m大小数组数组切成n份
   * @param array 数组
   * @param number 份数
   * @return
   */
  def splitArrayByNumber(array: Array[Byte],number: Int):List[Array[Byte]]={
    val list = new ListBuffer[Array[Byte]]
    val length: Int = array.length
    //求切分后长度，取余数
    val arraySize: Int = length / number
    val remainder: Int = length % number
    //数组复制
    val buffer: ByteBuffer = ByteBuffer.wrap(array)
    for (_ <- 1 until number){
      val subArray = new Array[Byte](arraySize)
      list.append(subArray)
      buffer.get(subArray,0,subArray.length)
    }
    //无法整除的情况,最后一个数组长度加上余数
    val last = new Array[Byte](arraySize + remainder)
    buffer.get(last,0,last.length)
    list.append(last)
    list.toList
  }
  def main(args: Array[String]): Unit = {
    val outputUrl = "D://scalaTo/"
    val inputUrl = "D://scalaSource/"
    //路径相同无法复制
    if (!inputUrl.equals(outputUrl)) {
      println(copyDirectory(inputUrl, outputUrl))
    }
  }
}
